import functools
import os
import fnmatch
import re
from typing import List, Generator, Tuple, Union

from moviepy.editor import VideoFileClip


# class SpecialStr:
#
#     @staticmethod
#     def cmp_for_filename(a: str, b: str) -> int:
#         # 结果为小于则返回一个负数
#         if a.isdigit() and b.isdigit():
#             return int(a) - int(b)
#         elif a.isdigit() and b.isdigit() is False:
#             return -1
#         elif a.isdigit() is False and b.isdigit():
#             return 1
#         else:
#             return a > b
#
#     def __init__(self, my_str):
#         self.my_str = my_str
#
#     def __gt__(self, other):
#         return self.cmp_for_filename(self.my_str, other.my_str)
#
#
# def cmp_for_SpecialStr_list(a: List[Union[str, List[SpecialStr]]], b: List[Union[str, List[SpecialStr]]]):
#     a = a[1]
#     b = b[1]
#     if len(a) != len(b):
#         return len(a) - len(b)
#     else:
#         for aa, bb in zip(a, b):
#             if aa < bb:
#                 return -1
#             elif aa > bb:
#                 return 1
#         return 0
#
#
# t_a = SpecialStr("1")
# t_b = SpecialStr("2")


# def enumerate_filename(sequence: str, start=0) -> str:
#     n = start
#     for elem in sequence:
#         yield n, elem
#         n += 1


# # 将字符和数字单独切割出来
# def split_file_name(file_name: str) -> List[SpecialStr]:
#     result: List[SpecialStr, None] = []
#     last_index = 0
#     last_char = file_name[0]
#     a_char: str  # 类型声明不强制检查, 只辅助第三方工具起到提示作用.
#     for now_index, a_char in enumerate(file_name):
#         if now_index == 0:
#             continue
#         if a_char.isdigit() != last_char.isdigit():
#             result.append(SpecialStr(file_name[last_index: now_index]))
#             last_index = now_index
#         last_char = a_char
#     result.append(SpecialStr(file_name[last_index:]))
#     return result

#
# def sorted_filename(file_name_list: List[str]) -> List[str]:
#     file_name_list = [[file_name, split_file_name(file_name)] for file_name in file_name_list]
#     file_name_list.sort(key=functools.cmp_to_key(cmp_for_SpecialStr_list))
#
#     return [f[0] for f in file_name_list]

# v0.1.1 修复数字不一定在首位的问题
def find_first_number(s:str)-> int:  
    matches = re.findall(r'\d+', s)  
    if matches:  
        return int(matches[0])  
    else:  
        return 0


def get_first_digit(s:str) -> int:
    match = re.search(r'^\d+', s)
    if match:
        return int(match.group())
    else:
        return 0

def find_files_with_extension(folder_path: str, file_extension: str, is_index_sort=True) -> list:
    """
    遍历指定文件夹及其子文件夹，查找所有指定文件尾缀名的文件，并返回文件列表。

    参数:
        folder_path (str): 文件夹路径。
        file_extension (str): 文件尾缀名，不包含点号。

    返回:
        list: 包含所有指定文件尾缀名的文件路径的列表。
    """

    if os.path.isdir(folder_path):
        # 初始化文件列表
        out_files = []
        file_extension = "*." + file_extension

        # 遍历文件夹及其子文件夹
        for root, dirs, files in os.walk(folder_path):
            # 遍历当前文件夹中的文件

            # 遍历前 - 序号字符串优化 - 探测并按照文件名首的数字来排序
            if is_index_sort:
                # files = sorted_filename(files)
                files.sort(key=find_first_number)

            for file in files:
                # 检查文件尾缀名是否匹配
                if fnmatch.fnmatch(file, file_extension):
                    # 将文件路径添加到列表中
                    out_files.append(os.path.join(root, file))

        return out_files
    else:
        raise NotADirectoryError(folder_path)


def get_video_duration(video_path: str) -> int:
    if os.path.isfile(video_path):
        clip = VideoFileClip(video_path)
        duration = clip.duration
        clip.close()
        return duration
    else:
        raise FileNotFoundError(video_path)
